/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package compilador;

import exceptions.ErroLexico;
import exceptions.ErroLexicoException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import lexico.Automato;
import lexico.Erro;
import sintatico.Sintatico;
import tabeladesimbolos.TabelaDeSimbolos;
import token.Token;
import token.TokenAll;
import token.TokenType;
import view.Janela;

/**
 *
 * @author joaocarlos
 */
public class Compilador333 implements Runnable{


    /**
     * Código fonte que será compilado
     */
    private String codigo;
    private LinkedList<ErroLexico> errosLexicos;

    /**
     * Tabela de simbolos para identificadores
     */
    private TabelaDeSimbolos tabela;

    /**
     * Lista de Tokens formada a partir do analizador lexico
     */
    private List<Token> lista_lexico;
    
    /**
     * Lista de Erros Sintaticos
     */
    private List<String> lista_Erro_Sint;

    /**
     * Interface com o usuário, permite adicionar mensagens ao usuário
     */
    private Janela janela;



    public Compilador333(Janela janela, String codigo){
        //Linka com a interface
        this.janela = janela;

        //Seta o Código
        this.codigo = codigo;

        //Cria as estruturas do Compilador
        lista_lexico = new ArrayList<Token>();
        tabela = new TabelaDeSimbolos();
       
    }

    /**
     * Executa todas as etapas de compilação chamando os metodos correspondentes das classes
     */
    public void run() {
        //Chama os processos de Análise
        //Transmite os resultados para a interface no pacote view
        Automato auto = new Automato();
        Sintatico sintatico = new Sintatico();
        String[] linhas;

        linhas = codigo.split("\n");

        //Processa as linhas do código
        for(int y = 0; y<linhas.length; y++)
        {
            System.out.println("Processando: " + linhas[y]);
            auto.controle(linhas[y]);
            System.out.println("Comentário:  "+ auto.getComent());
        }
        if(auto.getComent()==1)
            auto.getListErro().add(new Erro("Final de comentário não encontrado. ", "*/", -1));
        
        auto.imprimeLista();
        lista_lexico = auto.getListagem();
        
       
        sintatico.analiseTokens(lista_lexico);
        lista_Erro_Sint = sintatico.getErros();


        //Imprime os resultados do Lexico na Janela
        for(int i = 0; i<auto.getListagem().size(); i++)
        {
            if(auto.getListagem().get(i).geteToke().equals(TokenType.NUMERO) == false)
              janela.imprimeToken(lista_lexico.get(i).geteToke().name(), lista_lexico.get(i).getTipo().toString(),lista_lexico.get(i).getValor(), lista_lexico.get(i).getLinha());
            else
              janela.imprimeToken(lista_lexico.get(i).geteToke().name(), lista_lexico.get(i).getTipo().toString(), String.valueOf( lista_lexico.get(i).getValorNum()), lista_lexico.get(i).getLinha());
        }
        for(int i = 0; i<auto.getListErro().size(); i++)
        {
              janela.imprimeErro("Erro:  " +auto.getListErro().get(i).getTipo() + ",   valor:  " + auto.getListErro().get(i).getValor() +",   linha:   " + auto.getListErro().get(i).getLinha());
        }

        for(int i = 0; i<lista_Erro_Sint.size(); i++)
        {
              janela.imprimeErro(lista_Erro_Sint.get(i));
        }

        //Alimenta a tabela de simbolos
        for(int i = 0; i<lista_lexico.size(); i++){
            Token token = lista_lexico.get(i);
            
            //Adiciona apenas se o Token for identificador
            if(token.getTipo()==TokenAll.IDENTIFICADOR)
                tabela.inserir(token.getValor(), token);
        }
    }
}

